package cn.sunxyz.idea;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * Created by yangrd on 2017/5/23.
 */
public class SimpleCGLibDemo {

    static class RealService {
        public void sayHello() {
            System.out.println("hello");
        }
        public void hello(){
            System.out.println("hello world");
        }
    }

    static class Car {
       public void run(){
           System.out.println("Car:run()");
       }
    }

    static class SimpleInterceptor implements MethodInterceptor {

        @Override
        public Object intercept(Object object, Method method,
                                Object[] args, MethodProxy proxy) throws Throwable {
            System.out.println("entering " + method.getName());
            Object result = proxy.invokeSuper(object, args);
            System.out.println("leaving " + method.getName());
            return result;
        }
    }

    static class FirstInterceptor implements MethodInterceptor {

        private MethodInterceptor methodInterceptor;

        public FirstInterceptor(MethodInterceptor methodInterceptor) {
            this.methodInterceptor = methodInterceptor;
        }

        @Override
        public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
            System.out.println(method.getName());
            System.out.println("FirstInterceptor before " + method.getName());
            Object result = methodInterceptor.intercept(obj, method, args, proxy);
            System.out.println("FirstInterceptor after " + method.getName());
            return result;
        }
    }

    static Enhancer enhancer = new Enhancer();
    @SuppressWarnings("unchecked")
    private static <T> T getProxy(Class<T> cls) {
        enhancer.setSuperclass(cls);
        enhancer.setCallback(new FirstInterceptor(new SimpleInterceptor()));
        return (T) enhancer.create();
    }

    public static void main(String[] args) throws Exception {
        RealService proxyService = getProxy(RealService.class);
        proxyService.sayHello();
        proxyService.hello();
        Car car = getProxy(Car.class);
        car.run();
    }
}
